package org.huoran.sakamichi.main.zk;

import com.alibaba.fastjson.JSONObject;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import java.util.List;

public class ZkService implements InitializingBean, DisposableBean {

    private ZkClient zkClient;
    private String serverAddress;

    public ZkService(String serverAddress){
        this.serverAddress = serverAddress;
    }

    @Override
    public void afterPropertiesSet(){
        this.zkClient = new ZkClient(this.serverAddress);
    }

    @Override
    public void destroy(){
        this.zkClient.close();
    }

    public Object getNode(String nodePath){
        Boolean exists = this.zkClient.exists(nodePath);
        if(exists){
            Object nodeData = this.zkClient.readData(nodePath);
            System.out.println("ZKClient get node success:" + JSONObject.toJSONString(nodeData));
            return nodeData;
        }
        else{
            return null;
        }
    }

    public Boolean setNodeData(String nodePath, Object nodeData, CreateMode mode){
        try{
            Boolean exists = this.zkClient.exists(nodePath);
            String result;
            if(exists){
                this.zkClient.writeData(nodePath, nodeData);
                result = JSONObject.toJSONString(nodeData);
            }
            else{
                result = this.zkClient.create(nodePath, nodeData, mode);
            }
            System.out.println("ZKClient set node success:" + result);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public Boolean deleteNode(String nodePath){
        try{
            Boolean exists = this.zkClient.exists(nodePath);
            if(exists){
                this.zkClient.delete(nodePath);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public List<String> getChildren(String nodePath){
        try{
            List<String> children = this.zkClient.getChildren(nodePath);
            return children;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public boolean subscribe(String nodePath){
        try {
            if(!this.zkClient.exists(nodePath)){
                return false;
            }
            this.zkClient.subscribeChildChanges(nodePath, new IZkChildListener() {
                @Override
                public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
                    System.out.println("children has change : " + parentPath);
                }
            });
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
